#include "servermanager.h"
#include "datamanger.h"
#include <QTimer>

ServerManager::ServerManager(QString hostAddress, quint16 port, QObject *parent):
    QObject(parent),
    server(new QTcpServer(this)),
    listenIp(hostAddress),
    listenPort(port),
    meetingState(10, false),
    meetingList(10)
{
    connect(server,&QTcpServer::newConnection,this,&ServerManager::onNewConnection);
}

// 开启监听
void ServerManager::startServer()
{
    server->listen(listenIp,listenPort);
}

// 连接请求槽函数
void ServerManager::onNewConnection()
{
    QTcpSocket* client = server->nextPendingConnection();
    clientHandler* handler = new clientHandler(client,this);
    clienthandlers.insert(client,handler);
    connect(client, &QTcpSocket::disconnected, this, &ServerManager::onDisconnected);
    connect(handler, &clientHandler::userOnline, this, &ServerManager::onUserOnline);
    connect(handler, &clientHandler::getOnlineUsers, this, &ServerManager::onGetOnlineUsers);
    connect(handler, &clientHandler::privateChat, this, &ServerManager::onPrivateChat);
    connect(handler, &clientHandler::groupChat, this, &ServerManager::onGroupChat);
    connect(handler, &clientHandler::inviteGroup, this, &ServerManager::onInviteGroup);
    connect(handler, &clientHandler::addGroup, this, &ServerManager::onAddGroup);
    connect(handler, &clientHandler::groupFile, this, &ServerManager::onGroupFile);
    connect(handler, &clientHandler::meeting, this, &ServerManager::onMeeting);
    connect(handler, &clientHandler::inviteMeeting, this, &ServerManager::onInviteMeeting);
    connect(handler, &clientHandler::updateMeeting, this, &ServerManager::onUpdateMeeting);
    connect(handler, &clientHandler::quitMeeting, this, &ServerManager::onQuitMeeting);
    connect(handler, &clientHandler::clearMeeting, this, &ServerManager::onClearMeeting);


    emit clientConnected(client->peerAddress().toString(),client->peerPort());
}

// 添加在线用户槽函数
void ServerManager::onUserOnline(QString name, QTcpSocket *socket)
{
    userOnlineList[socket] = name;
    usersMap[name] = socket;
    QTimer::singleShot(500, this, &ServerManager::onGetOnlineUsers);
}

// 获取在线用户列表槽函数
void ServerManager::onGetOnlineUsers()
{
    messagePackage pack;
    pack.setType(messagePackage::OnlineUser);
    QStringList users;
    for (auto user : userOnlineList)
    {
        users.push_back(user);
    }
    pack.setOnlineUsers(users);
    for (auto client : userOnlineList.keys())
    pack.sendMessage(&pack, client);
}


// 用户断开连接槽函数
void ServerManager::onDisconnected()
{
    QTcpSocket *socket = static_cast<QTcpSocket*>(sender());
    if (userOnlineList.contains(socket))
    {
        datamanger::getInstance()->setLoginStat(userOnlineList[socket], 0);
    }
    for (int i = 0; i < meetingList.size(); i++)
    {
        if (meetingList[i].size() == 0) continue;
        if (meetingList[i][0] == userOnlineList[socket])
        {
            messagePackage pack;
            pack.setPort(i+8888);
            pack.setSender(userOnlineList[socket]);
            onClearMeeting(pack);
            break;
        }
    }
    userOnlineList.remove(socket);
    QTimer::singleShot(500, this, &ServerManager::onGetOnlineUsers);
}

// 用户私聊槽函数
void ServerManager::onPrivateChat(messagePackage pack)
{
    QString receiver = pack.receiver();
    QTcpSocket *client = nullptr;
    for (auto it = userOnlineList.begin(); it != userOnlineList.end(); ++it)
    {
        if (it.value() == receiver)
        {
            client = it.key();
            break;
        }
    }
    if (client == nullptr)
    {
        //qDebug() << "nobody";
        return ;
    }
    messagePackage::sendMessage(&pack,client);
}

// 群聊槽函数
void ServerManager::onGroupChat(messagePackage pack)
{
    pack.setType(messagePackage::GroupChat);
    QString groupName = pack.groupName();
    QString sender = pack.sender();
    QStringList users = datamanger::getInstance()->selectOneGroup(groupName);
    for (auto user : users)
    {

        if (user == pack.sender()) continue;
        if (usersMap.find(user) != usersMap.end())
        {
            messagePackage::sendMessage(&pack, usersMap[user]);
        }
    }
}

// 增加群成员
void ServerManager::onInviteGroup(messagePackage pack)
{
    QStringList users = datamanger::getInstance()->getAllUsers();
    QString user = pack.receiver();
    QString groupName = pack.groupName();
    if (users.count(user) == 0)
    {
        //qDebug() << "servermanager.cpp 113 : onInviteGroup ";
        return ;
    }
    bool ret = datamanger::getInstance()->inviteGroupInfo(user, groupName);
    if (!ret) return;
    if (usersMap.find(user) != usersMap.end())
    {
        messagePackage::sendMessage(&pack, usersMap[user]);
    }
}

// 在线群成员群列表更新
void ServerManager::onAddGroup(QStringList users, QString groupName, QString sender)
{
    messagePackage pack;
    pack.setType(messagePackage::InviteGroup);
    pack.setGroupName(groupName);
    pack.setSender(sender);
    for (auto user : users)
    {
        if (user == sender || usersMap.find(user) == usersMap.end()) continue;
        messagePackage::sendMessage(&pack, usersMap[user]);
    }
}


// 群聊消息槽函数
void ServerManager::onGroupFile(messagePackage pack)
{
    QString groupName = pack.groupName();
    QString sender = pack.sender();
    QStringList users = datamanger::getInstance()->selectOneGroup(groupName);
    for (auto user : users)
    {

        if (user == pack.sender()) continue;
        if (usersMap.find(user) != usersMap.end())
        {
            messagePackage::sendMessage(&pack, usersMap[user]);
        }
    }
}

// 创建会议
void ServerManager::onMeeting(messagePackage pack)
{
    int currentIp = -1;
    for (int i = 0; i < meetingState.size(); ++i)
    {
        if (!meetingState[i])
        {
            currentIp = i;
            meetingState[i] = true;
            meetingList[i].push_back(pack.sender());
            break;
        }
    }
    if (currentIp == -1)
    {
        pack.setRet(false);
        messagePackage::sendMessage(&pack, usersMap[pack.sender()]);
        return ;
    }
    QString ip = "224.0.0." + QString::number(currentIp + 10);
    quint16 port = 8888+currentIp;
    pack.setIp(ip);
    pack.setPort(port);
    pack.setRet(true);
    messagePackage::sendMessage(&pack, usersMap[pack.sender()]);
    datamanger::getInstance()->insertMeetingInfo(pack.meetingName(), pack.sender(), ip, port, pack.time());

    messagePackage invitePack(pack);
    invitePack.setType(messagePackage::InviteMeeting);
    for (auto user : pack.allUsers())
    {
        if (user == pack.sender()) continue;
        if (usersMap.find(user) == usersMap.end()) continue;
        messagePackage::sendMessage(&invitePack, usersMap[user]);
    }
}

// 邀请用户
void ServerManager::onInviteMeeting(messagePackage pack)
{
    if (usersMap.find(pack.receiver()) == usersMap.end()) return ;
    messagePackage::sendMessage(&pack, usersMap[pack.receiver()]);
}

// 更新会议在线人数列表
void ServerManager::onUpdateMeeting(messagePackage prevPack)
{
    int index = prevPack.port() - 8888;
    meetingList[index].push_back(prevPack.sender());
    messagePackage pack;
    pack.setType(messagePackage::UpdateMeeting);
    pack.setAllUsers(meetingList[index]);
    for (auto user : meetingList[index])
    {
        messagePackage::sendMessage(&pack, usersMap[user]);
    }
}

// 用户退出会议
void ServerManager::onQuitMeeting(messagePackage prevPack)
{
    int index = prevPack.port() - 8888;
    meetingList[index].removeOne(prevPack.sender());
    messagePackage pack;
    pack.setType(messagePackage::UpdateMeeting);
    pack.setAllUsers(meetingList[index]);
    for (auto user : meetingList[index])
    {
        messagePackage::sendMessage(&pack, usersMap[user]);
    }
}

// 会议结束
void ServerManager::onClearMeeting(messagePackage prevPack)
{
    int index = prevPack.port() - 8888;
    meetingState[index] = false;
    messagePackage pack;
    pack.setType(messagePackage::ClearMeeting);
    pack.setAllUsers(meetingList[index]);
    for (auto user : meetingList[index])
    {
        if (user == prevPack.sender()) continue;
        messagePackage::sendMessage(&pack, usersMap[user]);
    }
    meetingList[index].clear();
}

